$(function() {
	$('#solve').click(function() {
		disableCells();
		if (findSolution(sudokuMatrix)) {
			$('#playAgain').show();
		} else {
			alert("Antud sudoku ei ole lahendatav! Alustage uuesti!");
		}
	});

	$('#restart').click(function() {
		$('#number').val("");
		start();
	});
	start();
});

var availableCells;
var sudokuMatrix;
var cells = 4;
var tableWidth;
var cellWidth;
var lineWidth;
var currentNumber;

function start() {
	$('#playAgain').hide();
	init();
	initTable();
}

function init() {
	availableCells = new Array();
	sudokuMatrix = createEmptyMatrix();
	for ( var i = 1; i <= cells * cells; i++) {
		availableCells.push(i);
	}
}

function initTable() {
	tableWidth = 400;
	cellWidth = tableWidth / cells;
	lineWidth = tableWidth * 0.01;
	drawTable();
	drawCells();
	enableCells();
}

function drawTable() {
	var canvas = document.getElementById("tableCanvas");
	var context = canvas.getContext("2d");
	if (context) {
		var canvasWidth = tableWidth + 5 * lineWidth;
		context.canvas.width = canvasWidth;
		context.canvas.height = canvasWidth;
		context.lineWidth = lineWidth;
		context.beginPath();
		context.fillStyle = "rgb(0, 0, 0)";
		context.fillRect(0, 0, canvasWidth, canvasWidth);
		context.closePath();
	}
}

function drawCells() {
	for ( var i = 1; i <= 16; i++) {
		drawCell(i, false);
	}
}

function drawCell(cellId, active) {
	var cell = "cell" + cellId;
	var canvas = document.getElementById(cell);
	var context = canvas.getContext("2d");
	if (context) {
		context.canvas.width = cellWidth;
		context.canvas.height = cellWidth;
		cellId = cellId - 1;
		var x = (cellId % cells) * (cellWidth + lineWidth) + lineWidth;
		var y = ((cellId - (cellId % cells)) / cells) * (cellWidth + lineWidth)
				+ lineWidth;
		context.beginPath();
		if (active) {
			context.fillStyle = "rgb(200, 200, 200)";
		} else {
			context.fillStyle = "rgb(255, 255, 255)";
		}
		context.fillRect(0, 0, cellWidth, cellWidth);
		context.closePath();
		setLocation(cell, x, y);
	}
	return context;
}

function setLocation(id, x, y) {
	var x = $('#tableCanvas').position().left + x;
	var y = $('#tableCanvas').position().top + y;
	var id = '#' + id;
	$(id).css({
		'position' : 'absolute',
		'left' : x,
		'top' : y
	});
}

function disableCells() {
	for ( var i = 1; i <= cells * cells; i++) {
		$('#cell' + i).unbind();
	}
}

function disableCell(cellId) {
	$('#cell' + cellId).unbind();
}

function enableCells() {
	for ( var i = 0; i < availableCells.length; i++) {
		var id = '#cell' + availableCells[i];
		$(id).data("index", availableCells[i]);
		$(id).mouseover(function() {
			drawCell($(this).data('index'), true);
		});
		$(id).mouseout(function() {
			drawCell($(this).data('index'), false);
		});
		$(id).click(function() {
			drawNumber($(this).data('index'));
		});
	}
}

function createEmptyMatrix() {
	var newMatrix = [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ],
			[ 0, 0, 0, 0 ] ];
	return newMatrix;
}

function drawNumber(cellId) {
	var success = true;
	var currentNumber = parseInt(getCurrentNumber());
	switch (currentNumber) {
	case 1:
		drawOne(cellId);
		break;
	case 2:
		drawTwo(cellId);
		break;
	case 3:
		drawThree(cellId);
		break;
	case 4:
		drawFour(cellId);
		break;
	default:
		alert("Sisend vale, sisestage number 1-4");
		success = false;
		break;
	}
	if (success) {
		disableCell(cellId);
		removeCell(cellId);
		addNumberToMatrix(currentNumber, cellId);
	}
	$('#number').val("");
}

function drawOne(cellId) {
	var context = drawCell(cellId, false);
	if (context) {
		var lineWidth = cellWidth * 0.1;
		var numWidth = cellWidth / 3;
		var numHeight = 3 / 4 * cellWidth;
		context.beginPath();
		context.lineWidth = lineWidth;
		context.shadowOffsetX = 5;
		context.shadowOffsetY = 5;
		context.shadowBlur = 5;
		context.shadowColor = "rgb(150, 150, 150)";
		context.moveTo(cellWidth / 2 - numWidth / 2, cellWidth / 2);
		context.lineTo(cellWidth / 2 + numWidth / 2, cellWidth / 2 - numHeight
				/ 2 + 5);
		context.lineTo(cellWidth / 2 + numWidth / 2, cellWidth / 2 + numHeight
				/ 2);
		context.strokeStyle = "rgb(0,0,0)";
		context.stroke();
		context.closePath();
	}
}

function drawTwo(cellId) {
	var context = drawCell(cellId, false);
	if (context) {
		var lineWidth = cellWidth * 0.1;
		var numWidth = cellWidth / 2;
		var numHeight = 4 / 5 * cellWidth;
		context.beginPath();
		context.lineWidth = lineWidth;
		context.shadowOffsetX = 5;
		context.shadowOffsetY = 5;
		context.shadowBlur = 5;
		context.shadowColor = "rgb(150, 150, 150)";
		context.arc(cellWidth / 2, cellWidth / 2 - numHeight / 4 + 3,
				numWidth / 3, Math.PI * 1.1, Math.PI * 0.2, false);
		context.lineTo(cellWidth / 2 - numHeight / 4 + 3, cellWidth / 2
				+ numHeight / 4 + 3);

		context.lineTo(cellWidth / 2 + numWidth / 2, cellWidth / 2 + numHeight
				/ 4 + 3);

		context.strokeStyle = "rgb(0,0,0)";
		context.stroke();
		context.closePath();
	}
}

function drawThree(cellId) {
	var context = drawCell(cellId, false);
	if (context) {
		var lineWidth = cellWidth * 0.1;
		var numWidth = cellWidth / 2;
		var numHeight = 4 / 5 * cellWidth;
		context.beginPath();
		context.lineWidth = lineWidth;
		context.shadowOffsetX = 5;
		context.shadowOffsetY = 5;
		context.shadowBlur = 5;
		context.shadowColor = "rgb(150, 150, 150)";
		context.arc(cellWidth / 2, cellWidth / 2 - numHeight / 4 + 3,
				numWidth / 3, Math.PI * 0.5, Math.PI * 0.9, true);
		context.strokeStyle = "rgb(0,0,0)";
		context.stroke();
		context.closePath();
		context.beginPath();

		context.arc(cellWidth / 2, cellWidth / 2 + numHeight / 4 - 3,
				numWidth / 3, Math.PI * 1.1, Math.PI * 1.5, true);

		context.strokeStyle = "rgb(0,0,0)";
		context.stroke();
		context.closePath();
	}
}

function drawFour(cellId) {
	var context = drawCell(cellId, false);
	if (context) {
		var lineWidth = cellWidth * 0.1;
		var numWidth = cellWidth / 2;
		var numHeight = 4 / 5 * cellWidth;
		context.beginPath();
		context.lineWidth = lineWidth;
		context.shadowOffsetX = 5;
		context.shadowOffsetY = 5;
		context.shadowBlur = 5;
		context.shadowColor = "rgb(150, 150, 150)";
		context.moveTo(cellWidth / 2 + numWidth / 2 - 10, cellWidth / 2
				+ numHeight / 2);
		context.lineTo(cellWidth / 2 + numWidth / 2 - 10, cellWidth / 2
				- numHeight / 2);
		context.lineTo(cellWidth / 2 - numWidth / 2, 2 / 3 * cellWidth);
		context.lineTo(cellWidth / 2 + numWidth / 2, 2 / 3 * cellWidth);
		context.strokeStyle = "rgb(0,0,0)";
		context.stroke();
		context.closePath();
	}
}
function getCurrentNumber() {
	var number = $('#number').val();
	return number;
}

function addNumberToMatrix(number, cellId) {
	cellId--;
	var column = cellId % cells;
	var row = (cellId - column) / cells;
	sudokuMatrix[row][column] = number;
}

function removeCell(cellId) {
	for ( var i = 0; i < availableCells.length; i++) {
		if (cellId == availableCells[i]) {
			availableCells.splice(i, 1);
		}
	}
}

function drawNumbers(matrix) {
	var cell = 1;
	for ( var i = 0; i < matrix.length; i++) {
		for ( var j = 0; j < matrix[i].length; j++) {
			switch (matrix[i][j]) {
			case 1:
				drawOne(cell);
				break;
			case 2:
				drawTwo(cell);
				break;
			case 3:
				drawThree(cell);
				break;
			case 4:
				drawFour(cell);
				break;
			}
			cell++;
		}
	}
}